/*
 *  TransactionsQueue.java        22-ott-2009
 *   
 * Copyright (c) 2009 mentalsmash.org
 *  
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *  http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 * 
 *  The use of the Apache License does not indicate that this project is
 *  affiliated with the Apache Software Foundation.
 */

package org.mentalsmash.tazio.transactions.model;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import org.mentalsmash.tazio.IllegalArgumentException;
import org.mentalsmash.tazio.transactions.control.TazioTransaction;
import org.mentalsmash.tazio.transactions.control.impl.TazioTransactionImpl;
import org.mentalsmash.tazio.transactions.user.Transaction;

/**
 * The <tt>TransactionsQueue</tt> is a <i>thread-safe</i> FIFO queue were
 * transactions can be placed while awaiting for operations that will make them
 * proceed in their lifecycle.
 * <p>
 * For example transactions waiting for validation are inserted in a dedicated
 * FIFO queue
 * </p>
 * 
 * @author Andrea Reale
 * @version 0.0.1
 */
public class TransactionsQueue {

    /**
     * Maximum number of transactions in the queue, used if the no argument
     * constructor is used to create the <tt>TransactionsQueue</tt>
     */
    public final static int MAX_ELEMS_DEFAULT = 2 ^ 10;

    private final BlockingQueue<TazioTransactionImpl> queue;

    /**
     * Create a new <tt>TransactionsQueue</tt> capable of containing
     * {@link #MAX_ELEMS_DEFAULT} elements
     */
    public TransactionsQueue() {
	this.queue = new LinkedBlockingQueue<TazioTransactionImpl>(
		MAX_ELEMS_DEFAULT);
    }

    /**
     * Create a new <tt>TransactionsQueue</tt> capable of containing
     * <code>maxElements</code> elements
     * 
     * @param maxElements
     *            the maximum number of elements this queue will be able to
     *            manage
     */
    public TransactionsQueue(final int maxElements) {
	this.queue = new LinkedBlockingQueue<TazioTransactionImpl>(maxElements);
    }

    /**
     * Add a {@link Transaction} object to the queue. This operation does not
     * block, instead it may return false if the Queue is full.
     * 
     * @param tx
     *            the {@link Transaction} object to add to the queue
     * @return
     */
    public Boolean offer(final TazioTransactionImpl tx) {
	if (tx == null) {
	    throw new IllegalArgumentException(
		    "Cannot offer a null transaction");
	}
	return this.queue.offer(tx);
    }

    /**
     * Takes an element from the head of the queue, and block the calling thread
     * if no element can be retrieved
     * <p>
     * Elements are returned in FIFO order, and removed from the queue.
     * </p>
     * 
     * @return
     */
    public TazioTransaction take() throws InterruptedException {
	return this.queue.take();
    }

}
